#ifndef __MODBUS_H
#define	__MODBUS_H

#include "at32f435_437_wk_config.h"
#include "wk_system.h"

//定义设备地址，仅举例用，根据实际情况定义
#define MASTER_ADDRESS          0x01     //本机地址为0x01
#define SLAVE1_ADDRESS          0x02     //从机1地址为0x02
#define SLAVE2_ADDRESS          0x03     //从机2地址为0x03
//定义功能码
#define READ_COIL_REG           0x01     //读线圈
#define READ_DIS_INPUT_REG      0x02     //读离散输入
#define READ_HOLD_REG           0x03     //读保持寄存器
#define READ_INPUT_REG          0x04     //读输入寄存器
#define WRITE_SIN_COIL_REG      0x05     //写单个线圈
#define WRITE_SIN_HOLD_REG      0x06     //写单个保持寄存器
#define WRITE_MULT_COIL_REG     0x0F     //写多个线圈
#define WRITE_MULT_HOLD_REG     0x10     //写多个保持寄存器
//定义会操作到的寄存器地址，仅举例用，根据实际情况定义
#define DEV_SWITCH_REG          0x00    //设备开关状态寄存器
#define DEV_TEMP_REG            0x01    //设备温度寄存器

//定义Modbus数据结构
#define MODBUS_FRAME_LEN        256      //Modbus帧最大长度
#define MODBUS_DATA_LEN         250      //Modbus数据域最大长度

typedef struct {
    uint8_t frame[256];     //存放打包后或解析前的帧数据
    uint8_t address;        //设备地址
    uint8_t function;       //功能码
    uint16_t reg_addr;      //当操作单个寄存器时存放寄存器地址，当操作多个寄存器时存放起始地址
    uint16_t reg_num;       //当操作多个寄存器时存放操作寄存器数量
    uint8_t byte_num;       //写入或返回数据的字节数
    uint8_t data[250];      //数据域
    uint16_t crc;           //校验码
    uint16_t frame_len;     //打包帧时存放帧有效长度，方便串口发送用；解析帧时存放数据域有效数据长度，方便使用
} stc_modbus;

extern stc_modbus stcModbus;

//Modbus状态
static enum {
    M_SUCCESS = 0,M_ERROR
} ModbusStatus;

//Modbus初始化
void ModbusInit(void); 
//打包数据
uint8_t C_ModbusMakeData(stc_modbus *pstcModbus);
//解析数据
uint8_t C_ModbusParseData(stc_modbus *pstcModbus);
// 客户端解析数据
uint8_t S_ModbusParseData(stc_modbus *pstcModbus);
// 客户端打包数据
uint8_t S_ModbusMakeData(stc_modbus *pstcModbus);
//CRC查表法计算
uint16_t CRC16table(uint8_t *ptr, uint16_t len);
//void data_init(stc_modbus *pstcModbus);

#endif

